package cn.edu.cqie.impl;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import com.alibaba.fastjson.JSONObject;

import cn.edu.cqie.bo.LoginBo;
import cn.edu.cqie.dao.LogLoginLogDao;
import cn.edu.cqie.dao.UserInfoDao;
import cn.edu.cqie.entity.LogLoginLog;
import cn.edu.cqie.entity.UserInfo;
import cn.edu.cqie.enums.LoginSrcEnum;
import cn.edu.cqie.enums.RespToAppEnum;
import cn.edu.cqie.service.LoginService;
import cn.edu.cqie.utils.BizException;
import cn.edu.cqie.utils.CommonConstant;
import cn.edu.cqie.utils.HttpUtils;
import cn.edu.cqie.utils.JwtTokenUtil;

@Service
public class LoginImpl implements LoginService {

	@Autowired
	private UserInfoDao userInfoDao;

	@Autowired
	private LogLoginLogDao logLoginLogDao;

	private final static Logger logger = LoggerFactory.getLogger(LoginImpl.class);

	@Override
	public void wxLogin(LoginBo bo) {

		logger.info("LoginImpl-wxLogin-service-in,{}", JSONObject.toJSONString(bo));
		Map<String, String> params = new HashMap<String, String>();

		// 1.封装请求参数，调用微信登录校验接口
		params.put("appid", CommonConstant.APPID);
		params.put("secret", CommonConstant.SECRET);
		params.put("js_code", bo.getCode());
		params.put("grant_type", "authorization_code");

		logger.info("小程序登录凭证校验接口request,{}", JSONObject.toJSONString(params));
		String result = HttpUtils.doGet(CommonConstant.WX_URL_CODE2SESSION, params);
		logger.info("小程序登录凭证校验接口resp,{}", result);

		JSONObject wxResult = JSONObject.parseObject(result);
		// 2登录结果处理
		// 2.1如果结果为空则抛错
		if (ObjectUtils.isEmpty(wxResult)) {
			logger.info("小程序登录凭证校验接口resp-远程调用结果为空");
			throw new BizException(RespToAppEnum.LOGIN_ERROR_FOR_REMOTE_NULL);
		}
		// 2.2如果不成功
		if (ObjectUtils.isEmpty(wxResult.getString("openid"))) {
			logger.info("小程序登录凭证校验接口resp-登陆失败");
			throw new BizException(RespToAppEnum.LOGIN_ERROR);
		}

		// 3.如果当前用户未注册，则先注册用户，否则登录流水表中记录
		UserInfo userInfo = userInfoDao.findByOpenid(wxResult.getString("openid")).orElse(null);
		if (userInfo != null) {
			// 3.1如果已注册，则补充登录流水表
			insertToLoginLog(userInfo);
		} else {
			// 3.1如果未注册，则注册用户
			userInfo = insertToUserInfo(bo, wxResult);
		}

		// 4.生成token并装入bo返回
		bo.setToken(JwtTokenUtil.createJWT(CommonConstant.HOUR_24, null, userInfo.getId() + ""));
		bo.setOpenid(wxResult.getString("openid"));
	}

	private UserInfo insertToUserInfo(LoginBo bo, JSONObject wxResult) {
		// 1.添加用户
		UserInfo userInfo = new UserInfo();
		userInfo.setOpenid(wxResult.getString("openid"));
		userInfo.setState(CommonConstant.INTEGER_ONE);
		userInfoDao.save(userInfo);

		// 2.添加登录记录
		insertToLoginLog(userInfo);

		return userInfo;
	}

	private void insertToLoginLog(UserInfo userInfo) {
		LogLoginLog loginLog = new LogLoginLog();
		loginLog.setLoginSrc(LoginSrcEnum.WECHAT.getCode());
		loginLog.setUserId(userInfo.getId());
		logLoginLogDao.save(loginLog);
	}

}
